home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / net_src.arc / fingserv.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-05-08  |  5.7 KB  |  263 lines

  1.  
  2. /*
  3.  *
  4.  *    Finger support...
  5.  *
  6.  *    Finger server routines.  Written by Michael T. Horne - KA7AXD.
  7.  *    Copyright 1988 by Michael T. Horne, All Rights Reserved.
  8.  *    Permission granted for non-commercial use and copying, provided
  9.  *    that this notice is retained.
  10.  *
  11.  */
  12.  
  13. #include <stdio.h>
  14. #include "global.h"
  15. #include "mbuf.h"
  16. #include "timer.h"
  17. #include "internet.h"
  18. #include "icmp.h"
  19. #include "netuser.h"
  20. #include "tcp.h"
  21. #include "ftp.h"
  22. #include "telnet.h"
  23. #include "iface.h"
  24. #include "ax25.h"
  25. #include "lapb.h"
  26. #include "finger.h"
  27. #include "session.h"
  28. #include "nr4.h"
  29.  
  30. struct tcb *fing_tcb = NULLTCB;
  31. int16 finger_notify = 1;
  32.  
  33. finger1(argc, argv)
  34. int    argc;
  35. char    *argv[];
  36. {
  37.     extern int32    ip_addr;
  38.     struct socket    lsocket;
  39.     void        fing_state();
  40.     void        rcv_fing();
  41.  
  42.     if (fing_tcb)
  43.         return;
  44.     /* start finger daemon */
  45.     lsocket.address = ip_addr;
  46.     if(argc < 2)
  47.         lsocket.port = FINGER_PORT;
  48.     else
  49.         lsocket.port = atoi(argv[1]);
  50.     fing_tcb = open_tcp(&lsocket, NULLSOCK, TCP_SERVER, 0, rcv_fing,
  51.         NULLVFP, fing_state, 0, (int *)NULL);
  52.     return;
  53. }
  54. /*
  55.  *    Handle incoming finger connections and closures.
  56.  * 
  57.  */
  58. void
  59. fing_state(tcb,old,new)
  60. struct tcb    *tcb;
  61. char        old,        /* old state */
  62.         new;        /* new state */
  63. {
  64.     struct finger    *fing;
  65.     void        snd_fing();
  66.     char        *a;
  67.  
  68.     switch(new){
  69.     case ESTABLISHED:
  70.         log(tcb,"open Finger");
  71.         fing = (struct finger *) malloc(sizeof(struct finger));
  72.  
  73.         tcb->user = (char *)fing;    /* Upward pointer */
  74.         fing->tcb = tcb;        /* Downward pointer */
  75.         if (finger_notify)  {
  76.             printf("\007You're being fingered by %s!\n",
  77.                  psocket(&tcb->conn.remote));
  78.             fflush(stdout);
  79.         }
  80.         return;
  81.     case CLOSED:
  82.         if (tcb == fing_tcb)
  83.             fing_tcb = NULLTCB;
  84.         if (tcb->user != NULLCHAR)
  85.             free(tcb->user);
  86.         del_tcp(tcb);
  87.         break;
  88.     }
  89. }
  90.  
  91. /*
  92.  *    Stop the finger server.
  93.  */
  94.  
  95. finger0()
  96. {
  97.     if (fing_tcb != NULLTCB) {
  98.         close_tcp(fing_tcb);
  99.         fing_tcb = NULLTCB;
  100.     }
  101.     return;
  102. }
  103.  
  104. /*
  105.  *    Send a short message on a tcb
  106.  */
  107.  
  108. static
  109. sndmsg(tcb, msg)
  110. struct tcb    *tcb;        /* tcb to send on */
  111. char        *msg;        /* message to send */
  112. {
  113.     struct mbuf *bp;
  114.  
  115.     bp = qdata(msg,(int16)strlen(msg));
  116.     send_tcp(tcb,bp);
  117. }
  118.  
  119. /*
  120.  *    Finger receive upcall.  This is the guts of the finger server.
  121.  *    The user to finger is read from the socket.  If only a newline
  122.  *    is read, then send the remote host a list of all known 'users' on
  123.  *    this system.
  124.  */
  125.  
  126. void
  127. rcv_fing(tcb, ccnt)
  128. register struct tcb    *tcb;
  129. int16            ccnt;
  130. {
  131.     struct finger    *fing;
  132.     FILE        *fuser;
  133.     struct mbuf    *mbuf,
  134.             *bp;
  135.     char        *buf,
  136.             *who,
  137.             *finger_file,
  138.             *path,
  139.             ch,
  140.             temp[80],
  141.             user[80];
  142.     int        cnt;
  143.     int        size;
  144.  
  145.  
  146.     if ((fing = (struct finger *) tcb->user) == NULLFING)    /* uh oh! */
  147.         return;
  148.     if(recv_tcp(tcb,&bp,FINGNAMELEN) == 0)
  149.         return;
  150.     if ((who = malloc(FINGNAMELEN + 1)) == NULL) {
  151.         free_p(bp);
  152.         return;
  153.     }
  154.  
  155.     cnt = pullup(&bp, who, FINGNAMELEN);    /* get 'user' name */
  156.     who[cnt] = '\0';            /* NULL terminate it */
  157.     free_p(bp);                /* all done with bp */
  158.  
  159.     if (*who == '\015' || *who == '\012') {    /* give him a user listing */
  160.         int found = 0;
  161.  
  162.         path = (char *) malloc(strlen(fingerpath) + strlen(fingersuf)
  163.             + 2);
  164.         /* create wildcard path to finger files */
  165.         strcpy(path, fingerpath);
  166.         strcat(path, "*");
  167.         strcat(path, fingersuf);
  168.  
  169.         sndmsg(tcb, "Known users on this system:\015\012");
  170.         for (filedir(path, 0, user); user[0] != '\0';
  171.             filedir (path, 1, user))  {
  172.             found++;
  173.             *index(user, '.') = '\0';
  174.             sprintf(temp, "        %s\015\012", user);
  175.             sndmsg(tcb, temp);
  176.         }
  177.         if (!found)
  178.             sndmsg(tcb, "None!\015\012");
  179.  
  180.         free(path);
  181.     }
  182.     else {
  183.         buf = who;
  184.         while (*buf != '\015' && *buf != '\012' && *buf != '\0')
  185.             buf++;
  186.         *buf = '\0';
  187.         /*
  188.          *    Create path to user's finger file and see if the
  189.          *    the file exists.
  190.          */
  191.         finger_file = malloc(strlen(fingerpath) + strlen(who)
  192.                 + strlen(fingersuf) + 1);
  193.         if (finger_file == NULLCHAR) {    /* uh oh... */
  194.             free(who);        /* clean up */
  195.             close_tcp(tcb);        /* close socket */
  196.             return;
  197.         }
  198.         strcpy(finger_file, fingerpath);
  199.         strcat(finger_file, who);
  200.         strcat(finger_file, fingersuf);
  201.  
  202.         if ((fuser = fopen(finger_file, "r")) == (FILE *) NULL) {
  203.             sprintf(temp, "User %s unknown on this system\015\012",
  204.                 who);
  205.             sndmsg(tcb, temp);
  206.         }
  207.         else {                /* valid 'user' */
  208.             char    nl = '\0';    /* newline flag */
  209.  
  210.             /*
  211.              * Here's a tricky routine to make sure we get
  212.              * everything in, including "\r\n".  It's needed since
  213.              * UNIX files have only a '\n' for EOL.  What is
  214.              * REALLY NEEDED is a standardized routine for filling
  215.              * mbufs from file input so that each server doesn't
  216.              * have to do it themselves!  Ditto for emptying
  217.              * mbufs!  The problem of "\r\n" doesn't rear its
  218.              * ugly head with MessyDOS, but with UNIX boxes...
  219.              */
  220.  
  221.             ch = fgetc(fuser);    /* first get must be outside */
  222.             while (!feof(fuser)) {
  223.                 size = tcb->window;
  224.                 if ((mbuf = alloc_mbuf(size)) == NULLBUF) {
  225.                     fclose(fuser);    /* barf */
  226.                     free(who);
  227.                     free(finger_file);
  228.                     return;
  229.                 }
  230.                 buf = mbuf->data;    /* pointer to buffer */
  231.                 while(!feof(fuser) && size--) {    /* loop */
  232.                     if (nl) {
  233.                         *buf++ = '\012';/* line feed */
  234.                         mbuf->cnt++;
  235.                         nl--;
  236.                     }
  237.                     else switch(ch) {
  238.                         case '\032':    /* NO ^Z's! */
  239.                             break;
  240.                         case '\012':    /* ignore LF */
  241.                             break;
  242.                         case '\015':    /* EOL */
  243.                             nl++;    /* fall thru */
  244.                         default:
  245.                             *buf++ = ch;
  246.                             mbuf->cnt++;
  247.                             break;
  248.                     }
  249.                     if (!nl)
  250.                         ch = fgetc(fuser);
  251.                 }
  252.                 send_tcp(tcb, mbuf);    /* send info */
  253.             }
  254.             fclose(fuser);
  255.         }
  256.         free(finger_file);
  257.     }
  258.     free(who);
  259.     close_tcp(tcb);            /* close socket */
  260.     return;
  261. }
  262.  
  263.